package hr.fer.zpr.nmbp.project1.dao;

import hr.fer.zpr.nmbp.project1.dao.exceptions.PrimaryKeyConstraintException;
import hr.fer.zpr.nmbp.project1.model.Bolest;
import hr.fer.zpr.nmbp.project1.model.Dijagnoza;
import hr.fer.zpr.nmbp.project1.model.Karton;

import java.util.Date;
import java.util.List;

import com.db4o.ObjectContainer;
import com.db4o.constraints.UniqueFieldValueConstraintViolationException;
import com.db4o.query.Predicate;

public class DijagnozaDAO {

	private ObjectContainer db;

	public DijagnozaDAO(ObjectContainer db) {
		this.db = db;
	}

	public void save(Dijagnoza dijagnoza) {
		if (dijagnoza.getSifra() == null || dijagnoza.getSifra().isEmpty()) {
			throw new PrimaryKeyConstraintException(
					"Šifra dijagnoze ne smije biti NULL");
		}

		this.db.store(dijagnoza);

		try {
			this.db.commit();
		} catch (UniqueFieldValueConstraintViolationException e) {
			this.db.rollback();
			throw new PrimaryKeyConstraintException(
					"Šifra dijagnoze već postoji u bazi podataka");
		}
	}

	public void delete(Dijagnoza dijagnoza) {
		Karton refKarton = dijagnoza.getKarton();

		if (refKarton != null) {
			refKarton.getDijagnoze().remove(dijagnoza);
		}

		this.db.delete(dijagnoza);
		this.db.commit();
	}

	public List<Dijagnoza> load(Dijagnoza dijagnozaPrototype) {
		return this.db.queryByExample(dijagnozaPrototype);
	}

	public List<Dijagnoza> loadAll() {
		return this.db.query(Dijagnoza.class);
	}

	public List<Dijagnoza> load(final Date dateFrom, final Date dateTo) {
		@SuppressWarnings("serial")
		List<Dijagnoza> dijagnoze = this.db.query(new Predicate<Dijagnoza>() {

			@Override
			public boolean match(Dijagnoza dijagnoza) {
				if(dateFrom == null && dateTo != null){
					return dijagnoza.getDatum().compareTo(dateTo) <= 0; 
				}else if(dateFrom != null && dateTo == null){
					return dijagnoza.getDatum().compareTo(dateFrom) >= 0;
				}else if(dateFrom != null && dateTo != null){
					return dijagnoza.getDatum().compareTo(dateFrom) >= 0 &&
							dijagnoza.getDatum().compareTo(dateTo) <= 0;
				}else{
					return false;
				}
			}
		});
		
		return dijagnoze;
	}
	
	public List<Dijagnoza> load(final List<Bolest> bolesti){
		@SuppressWarnings("serial")
		List<Dijagnoza> dijagnoze = this.db.query(new Predicate<Dijagnoza>() {

			@Override
			public boolean match(Dijagnoza dijagnoza) {
				for(Bolest bolest : bolesti){
					if(dijagnoza.getBolesti().contains(bolest)){
						return true;
					}
				}
				
				return false;
			}
		});
		
		return dijagnoze;
	}
}
